diff --git a/swh/web/common/swh_templatetags.py b/swh/web/common/swh_templatetags.py index 43ca3941..091121f0 100644 --- a/swh/web/common/swh_templatetags.py +++ b/swh/web/common/swh_templatetags.py @@ -1,82 +1,82 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information import re from docutils.core import publish_parts from docutils.writers.html4css1 import Writer, HTMLTranslator from inspect import cleandoc from django import template register = template.Library() class NoHeaderHTMLTranslator(HTMLTranslator): """ Docutils translator subclass to customize the generation of HTML from reST-formatted docstrings """ def __init__(self, document): super().__init__(document) self.body_prefix = [] self.body_suffix = [] def visit_bullet_list(self, node): self.context.append((self.compact_simple, self.compact_p)) self.compact_p = None self.compact_simple = self.is_compactable(node) self.body.append(self.starttag(node, 'ul', CLASS='docstring')) DOCSTRING_WRITER = Writer() DOCSTRING_WRITER.translator_class = NoHeaderHTMLTranslator @register.filter def safe_docstring_display(docstring): """ Utility function to htmlize reST-formatted documentation in browsable api. """ docstring = cleandoc(docstring) return publish_parts(docstring, writer=DOCSTRING_WRITER)['html_body'] @register.filter -def urlize_api_links(text): +def urlize_links_and_mails(text): """Utility function for decorating api links in browsable api. Args: text: whose content matching links should be transformed into contextual API or Browse html links. Returns The text transformed if any link is found. The text as is otherwise. """ text = re.sub(r'(/api/[^"<]*/|/browse/.*/|http.*$)', r'\1', text) return re.sub(r'([^ <>"]+@[^ <>"]+)', r'\1', text) @register.filter def urlize_header_links(text): """Utility function for decorating headers links in browsable api. Args text: Text whose content contains Link header value Returns: The text transformed with html link if any link is found. The text as is otherwise. """ return re.sub(r'<(/api/.*|/browse/.*)>', r'<\1>', text) diff --git a/swh/web/templates/apidoc.html b/swh/web/templates/apidoc.html index 55d9ae11..753eb1a6 100644 --- a/swh/web/templates/apidoc.html +++ b/swh/web/templates/apidoc.html @@ -1,149 +1,149 @@ {% extends "layout.html" %} {% load swh_templatetags %} {% load static %} {% block title %}{{ heading }} – Software Heritage API {% endblock %} {% block header %} {% endblock %} {% block content %} {% if docstring %}

Description

{{ docstring | safe_docstring_display | safe }}
{% endif %} {% if response_data %}

Request

{{ request.method }} {{ request.build_absolute_uri }}

Response

{% if status_code != 200 %}

Status Code

{{ status_code }}
{% endif %} {% if headers_data %}

Headers

{% for header_name, header_value in headers_data.items %}
{{ header_name }} {{ header_value | urlize_header_links | safe }}
{% endfor %} {% endif %}

Body

-      {{ response_data | urlize_api_links | safe }}
+      {{ response_data | urlize_links_and_mails | safe }}
     
{% endif %}
{% if urls and urls|length > 0 %}
{% for url in urls %} {% endfor %}
URL Allowed Methods
{{ url.rule }} {{ url.methods | dictsort:0 | join:', ' }}

{% endif %} {% if args and args|length > 0 %}

Arguments

{% for arg in args %}
{{ arg.name }}: {{ arg.type }}
{{ arg.doc | safe_docstring_display | safe }}
{% endfor %}

{% endif %} {% if params and params|length > 0 %}

Parameters

{% for param in params %}
{{ param.name }}: {{ param.type }}
{{ param.doc | safe_docstring_display | safe }}
{% endfor %}

{% endif %} {% if headers and headers|length > 0 %}

Headers

{% for header in headers %}
{{ header.name }}: string
{{ header.doc | safe_docstring_display | safe }}
{% endfor %}

{% endif %} {% if returns and returns|length > 0 %}

Returns

{% for return in returns %}
{{ return.type }}
{{ return.doc | safe_docstring_display | safe }}
{% endfor %}

{% endif %} {% if excs and excs|length > 0 %}

Errors

{% for exc in excs %}
{{ exc.exc }}
{{ exc.doc | safe_docstring_display | safe }}
{% endfor %}

{% endif %} {% if examples and examples|length > 0 %}

Examples

{% for example in examples %}
{{ example }}
{% endfor %}
{% endif %} {% endblock %} diff --git a/swh/web/templates/origin.html b/swh/web/templates/origin.html index 04f029d4..91a73871 100644 --- a/swh/web/templates/origin.html +++ b/swh/web/templates/origin.html @@ -1,71 +1,71 @@ {% extends "layout.html" %} {% load static %} {% load swh_templatetags %} {% block title %}Origin information{% endblock %} {% block content %}

Origin information

{% for key, val in origin.items|dictsort:0 %} - + {% endfor %}
{{ key }}{{ val | safe | urlize_api_links | safe }}{{ val | safe | urlize_links_and_mails | safe }}

Origin visit history

Calendar

Visit list

{% for v in visits %} {% endfor %}
Visit id Visit date Visit status Browse revision url
{{ v.visit }} {{ v.date }} {{ v.status }} {{ v.browse_url }}
{% endblock %} diff --git a/swh/web/templates/person.html b/swh/web/templates/person.html index c13efda1..15c39463 100644 --- a/swh/web/templates/person.html +++ b/swh/web/templates/person.html @@ -1,16 +1,16 @@ {% extends "layout.html" %} {% load swh_templatetags %} {% block title %}Person{% endblock %} {% block content %}

Person information

{% for key, val in person.items|dictsort:0 %} - + {% endfor %}
{{ key }}{{ val | safe | urlize_api_links | escape | safe }}{{ val | safe | urlize_links_and_mails | escape | safe }}
{% endblock %} diff --git a/swh/web/tests/common/test_templatetags.py b/swh/web/tests/common/test_templatetags.py index 29f36f85..67e5e56f 100644 --- a/swh/web/tests/common/test_templatetags.py +++ b/swh/web/tests/common/test_templatetags.py @@ -1,66 +1,66 @@ # Copyright (C) 2015-2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import unittest from nose.tools import istest from swh.web.common import swh_templatetags class SWHTemplateTagsTest(unittest.TestCase): @istest def urlize_api_links_api(self): # update api link with html links content with links content = '{"url": "/api/1/abc/"}' expected_content = ('{"url": "/api/1/abc/"}') - self.assertEquals(swh_templatetags.urlize_api_links(content), + self.assertEquals(swh_templatetags.urlize_links_and_mails(content), expected_content) @istest def urlize_api_links_browse(self): # update /browse link with html links content with links content = '{"url": "/browse/def/"}' expected_content = ('{"url": "' '/browse/def/"}') - self.assertEquals(swh_templatetags.urlize_api_links(content), + self.assertEquals(swh_templatetags.urlize_links_and_mails(content), expected_content) @istest def urlize_header_links(self): # update api link with html links content with links content = """; rel="next" ; rel="prev" """ expected_content = """</api/1/abc/>; rel="next" </api/1/def/>; rel="prev" """ self.assertEquals(swh_templatetags.urlize_header_links(content), expected_content) @istest def safe_docstring_display(self): # update api link with html links content with links docstring = """This is my list header: - Here is item 1, with a continuation line right here - Here is item 2 Here is something that is not part of the list""" expected_docstring = """

This is my list header:

Here is something that is not part of the list

""" self.assertEquals(swh_templatetags.safe_docstring_display(docstring), expected_docstring)